﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace lfm.EndPoints
{
    public class Artist
    {
        /// <summary>
        /// Get the metadata for an artist. Includes biography.
        /// </summary>
        /// <param name="Artist">The artist name</param>
        /// <param name="Language">OPTIONAL - The language to return the biography in, expressed as an ISO 639 alpha-2 code.</param>
        /// <param name="Autocorrect">Transform misspelled artist names into correct artist names, returning the correct version instead. The corrected artist name will be returned in the response.</param>
        /// <returns></returns>
        public static async Task<lfm.Artist> getInfo(String Artist, String Language, Boolean? Autocorrect)
        {
            String s = String.Format("{0}&method=artist.getInfo&artist={1}", Base.APIUrl, Uri.EscapeDataString(Artist));
            if (!String.IsNullOrEmpty(Language)) s += "&lang=" + Language.ToString();
            if (Autocorrect.HasValue && Autocorrect.Value) s += "&autocorrect=1";

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Artist.getInfo(await Base.DownloadString(u));
        }

        /// <summary>
        /// Gets a list of upcoming events for an artist 
        /// </summary>
        /// <param name="Artist">The artist name</param>
        /// <param name="Page">The page number to fetch. Defaults to first page</param>
        /// <param name="Limit">The number of results to fetch per page. Defaults to 50</param>
        /// <param name="Autocorrect">Transform misspelled artist names into correct artist names, returning the correct version instead. The corrected artist name will be returned in the response</param>
        /// <returns>Upcoming events for this artist</returns>
        public static async Task<List<lfm.Event>> getEvents(String Artist, Int32? Page, Int32? Limit, Boolean? Autocorrect)
        {
            String s = String.Format("{0}&method=artist.getevents&artist={1}", Base.APIUrl, Uri.EscapeDataString(Artist));
            if (Page.HasValue) s += "&page=" + Page.Value.ToString();
            if (Autocorrect.HasValue && Autocorrect.Value) s += "&autocorrect=1";
            if (Limit.HasValue) s += "&limit=" + Limit.Value.ToString();

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Artist.getEvents(await Base.DownloadString(u));
        }

        /// <summary>
        /// Gets a list of images for an artist in a variety of sizes
        /// </summary>
        /// <param name="Artist">The artist name</param>
        /// <param name="Page">The page number to fetch. Defaults to first page</param>
        /// <param name="Limit">The number of results to fetch per page. Defaults to 50</param>
        /// <param name="Autocorrect">Transform misspelled artist names into correct artist names, returning the correct version instead. The corrected artist name will be returned in the response</param>
        /// <param name="order">Sort ordering can be either 'popularity' (default) or 'dateadded'. While ordering by popularity officially selected images by labels and artists will be ordered first</param>
        /// <returns>Images for this artist in a variety of sizes</returns>
        public static async Task<List<lfm.Image>> getImages(String Artist, Int32? Page, Int32? Limit, Boolean? Autocorrect, Order? order)
        {
            String s = String.Format("{0}&method=artist.getImages&artist={1}", Base.APIUrl, Uri.EscapeDataString(Artist));
            if (Limit.HasValue) s += "&limit=" + Limit.Value.ToString();
            if (Page.HasValue) s += "&page=" + Page.Value.ToString();
            if (Autocorrect.HasValue && Autocorrect.Value) s += "&autocorrect=1";
            if (order.HasValue && order.Value == Order.dateadded) s += "&order=dateadded";

            Uri u = new Uri(s);
            String httpresponse = await Base.DownloadString(u);
            List<lfm.Image> result = await Parser.Artist.getImages(httpresponse);
            return result;
        }

        /// <summary>
        /// Gets a list of shouts for an artist 
        /// </summary>
        /// <param name="Artist">The artist name</param>
        /// <param name="Page">The page number to fetch. Defaults to first page</param>
        /// <param name="Limit">The number of results to fetch per page. Defaults to 50</param>
        /// <param name="Autocorrect">Transform misspelled artist names into correct artist names, returning the correct version instead. The corrected artist name will be returned in the response</param>
        /// <returns>Shouts for this artist</returns>
        public static async Task<List<lfm.Shout>> getShouts(String Artist, Int32? Page, Int32? Limit, Boolean? Autocorrect)
        {
            String s = String.Format("{0}&method=artist.getShouts&artist={1}", Base.APIUrl, Uri.EscapeDataString(Artist));
            if (Page.HasValue) s += "&page=" + Page.Value.ToString();
            if (Autocorrect.HasValue && Autocorrect.Value) s += "&autocorrect=1";
            if (Limit.HasValue) s += "&limit=" + Limit.Value.ToString();

            Uri u = new Uri(s);
            String httpresponse = await Base.DownloadString(u);
            List<lfm.Shout> result = await Parser.Generic.getShouts(httpresponse);
            return result;
        }

        /// <summary>
        /// Gets a list of similar artists for an artist 
        /// </summary>
        /// <param name="Artist">The artist name</param>
        /// <param name="Limit">The number of results to fetch per page. Defaults to 50</param>
        /// <param name="Autocorrect">Transform misspelled artist names into correct artist names, returning the correct version instead. The corrected artist name will be returned in the response</param>
        /// <returns>Similar artists for this artist</returns>
        public static async Task<List<lfm.Artist>> getSimilar(String Artist, Int32? Limit, Boolean? Autocorrect)
        {
            String s = String.Format("{0}&method=artist.getSimilar&artist={1}", Base.APIUrl, Uri.EscapeDataString(Artist));
            if (Autocorrect.HasValue && Autocorrect.Value) s += "&autocorrect=1";
            if (Limit.HasValue) s += "&limit=" + Limit.Value.ToString();

            Uri u = new Uri(s);
            String httpresponse = await Base.DownloadString(u);
            List<lfm.Artist> result = await Parser.Artist.getSimilar(httpresponse);
            return result;
        }

        /// <summary>
        /// Gets a list of the most popular tags for an artist 
        /// </summary>
        /// <param name="Artist">The artist name</param>
        /// <param name="Autocorrect">Transform misspelled artist names into correct artist names, returning the correct version instead. The corrected artist name will be returned in the response</param>
        /// <returns>Top Tags for this artist</returns>
        public static async Task<List<lfm.Tag>> getTopTags(String Artist, Boolean? Autocorrect)
        {
            String s = String.Format("{0}&method=artist.gettoptags&artist={1}", Base.APIUrl, Uri.EscapeDataString(Artist));
            if (Autocorrect.HasValue && Autocorrect.Value) s += "&autocorrect=1";

            Uri u = new Uri(s);
            return await Parser.Generic.getTags(await Base.DownloadString(u));
        }

        /// <summary>
        /// Gets a list of top albums for an artist 
        /// </summary>
        /// <param name="Artist">The artist name</param>
        /// <param name="Page">The page number to fetch. Defaults to first page</param>
        /// <param name="Limit">The number of results to fetch per page. Defaults to 50</param>
        /// <param name="Autocorrect">Transform misspelled artist names into correct artist names, returning the correct version instead. The corrected artist name will be returned in the response</param>
        /// <returns>Top Albums for this artist</returns>
        public static async Task<List<lfm.Album>> getTopAlbums(String Artist, Int32? Page, Int32? Limit, Boolean? Autocorrect)
        {
            String s = String.Format("{0}&method=artist.gettopalbums&artist={1}", Base.APIUrl, Uri.EscapeDataString(Artist));
            if (Page.HasValue) s += "&page=" + Page.Value.ToString();
            if (Autocorrect.HasValue && Autocorrect.Value) s += "&autocorrect=1";
            if (Limit.HasValue) s += "&limit=" + Limit.Value.ToString();

            Uri u = new Uri(s);
            String httpresponse = await Base.DownloadString(u);
            List<lfm.Album> result = await Parser.Artist.getTopAlbums(httpresponse);
            return result;
        }

        /// <summary>
        /// Gets a list of top tracks for an artist 
        /// </summary>
        /// <param name="Artist">The artist name</param>
        /// <param name="Page">The page number to fetch. Defaults to first page</param>
        /// <param name="Limit">The number of results to fetch per page. Defaults to 50</param>
        /// <param name="Autocorrect">Transform misspelled artist names into correct artist names, returning the correct version instead. The corrected artist name will be returned in the response</param>
        /// <returns>Top Tracks for this artist</returns>
        public static async Task<List<lfm.Track>> getTopTracks(String Artist, Int32? Page, Int32? Limit, Boolean? Autocorrect)
        {
            String s = String.Format("{0}&method=artist.gettoptracks&artist={1}", Base.APIUrl, Uri.EscapeDataString(Artist));
            if (Page.HasValue) s += "&page=" + Page.Value.ToString();
            if (Autocorrect.HasValue && Autocorrect.Value) s += "&autocorrect=1";
            if (Limit.HasValue) s += "&limit=" + Limit.Value.ToString();

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Generic.getTracks(await Base.DownloadString(u));
        }

        /// <summary>
        /// Gets a list of search results for an artist 
        /// </summary>
        /// <param name="Artist">The artist name</param>
        /// <param name="Page">The page number to fetch. Defaults to first page</param>
        /// <param name="Limit">The number of results to fetch per page. Defaults to 50</param>
        /// <returns>Shouts for this artist</returns>
        public static async Task<List<lfm.Artist>> search(String Artist, Int32? Page, Int32? Limit)
        {
            String s = String.Format("{0}&method=artist.search&artist={1}", Base.APIUrl, Uri.EscapeDataString(Artist));
            if (Page.HasValue) s += "&page=" + Page.Value.ToString();
            if (Limit.HasValue) s += "&limit=" + Limit.Value.ToString();

            Uri u = new Uri(s);
            String httpresponse = await Base.DownloadString(u);
            List<lfm.Artist> result = await Parser.Artist.search(httpresponse);
            return result;
        }
    }
}
